﻿using System;
using AgateLib.DisplayLib;
using AgateLib.Sprites;
using AiAsteriods.Game.Entities.OpenSteerDotNet;
using AiAsteriods.Game.State;

namespace AiAsteriods.Game.Entities.Base {
  abstract class EntityAbstract : SimpleVehicle {
    protected Sprite mySprite = null;
    protected GameStateAbstract myState;

    private EntityAbstract collidedWith = null;

    public double X { get; set; }
    public double Y { get; set; }
    public double Dx { get; set; }
    public double Dy { get; set; }
    public double Drot { get; set; }
    public double Rotation { get; set; }
    public double Speed { get; set; }
    public double Radius { get; set; }
    public int CollisionDamage { get; set; }
    public int LifeTime { get; set; }
    public int TotalLife { get; set; }
    protected double DegreeToRad = Math.PI / 180;
    protected double RadToDegree = 180 / Math.PI;

    public EntityAbstract() { 
    }

    public EntityAbstract(Sprite s, int x, int y, double rot, double speed, double radius, int collisionDamage, int lifeTime, GameStateAbstract state) {
      mySprite = s;

      myState = state;

      Dx = 0.0d;
      Dy = 0.0d;
      Drot = 0.0d;

      this.LifeTime = lifeTime;
      this.Speed = speed;
      this.X = x;
      this.Y = y;
      this.Rotation = rot;
      this.Radius = radius;
      this.CollisionDamage = collisionDamage;
    }

    public virtual void Update(int delta) {
      TotalLife += delta;

      Dx = Math.Sin(Rotation * DegreeToRad);
      Dy = Math.Cos(Rotation * DegreeToRad);

      X += Dx * Speed * delta;
      Y += Dy * Speed * delta;

      Rotation += Drot * delta;

      if (((X < -500) || (X > myState.GS.ScreenWidth + 500)) || ((Y < -500) || (Y > myState.GS.ScreenHeight + 500))) {
        myState.RemoveEntity(this);
      }

      mySprite.Update(delta);
    }

    public virtual void Draw() {
      mySprite.RotationAngleDegrees = Rotation - 90;
      mySprite.DisplayAlignment = OriginAlignment.Center;
      mySprite.Draw((int)X, (int)Y);
    }

    public virtual void Collide(EntityAbstract e) {
      myState.RemoveEntity(this);
      mySprite.Dispose();
    }

    public virtual Boolean CollisionTest(EntityAbstract e) {
      int radius1 = (int)e.Radius;
      int radius2 = (int)this.Radius;

      int dx = (int)(this.X - e.X);
      int dy = (int)(this.Y - e.Y);
      int radii = radius1 + radius2;
      if ((dx * dx) + (dy * dy) < radii * radii) {
        return true;
      }
      return false;
    }

    public EntityAbstract ICollidedWith() {
      return collidedWith;
    }

    public void SetAlpha(int alpha) {
      mySprite.Alpha = alpha;
    }
  }
}